iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 7
0
自我挑戰組

30 天的 ShellScript 教室解決開發者的困擾系列 第 7

[鐵人賽第07天] 介紹 stdout / stderr

  • 分享至 

  • xImage
  •  

今天來講講打完指令在螢幕上顯示的東西吧。

首先,會出現在終端機畫面上的資訊,有兩種:

  • stdout
  • stderr

stdout 通常用來輸出一般的資訊, stderr 通常則用來輸出錯誤資訊(但是有利外)。下面舉的例子吧:
執行指令find -name myFile

因為 find 指令進不去 folder3 所以有一個錯誤訊息。那 stdoutstderr 有差嗎?反正都是顯示在終端機上不是嗎?

平常確實沒有什麼差異,但是如果今天我們透過輸出重新定向 > ,把指令的結果輸出到檔案呢:
輸出指令結果

注意到了嗎,加上重新定向符號 > 後, find: ‘./folder3’: 拒絕不符權限的操作 這行依然顯示在螢幕上,沒有被存進去 myFileLocation.txt 。如果要把 stderr 的結果輸出到檔案,要用 2> 來把它輸出到檔案:

find -name myFile > myFileLocation.txt 2> myFileLocation-Error.txt

執行這個指令後,你會發現終端機上聯錯誤訊息都沒有顯示,而且錯誤訊息也真的被存在 myFileLocation-Error.txt 裡面:
重新定向stderr

當然如果你不希望覆蓋掉原本的檔案,可以用 >> 來取代 > ,也就是開啟檔案時,是 a 模式還是 w 模式。

不過有沒有例外?當然有,像是 ffmpeg 常常會需要把檔案解碼後,丟給下一隻程式像是 x264 處理,這時候 stdout 就會被拿來輸出解碼後的內容,而 stderr 則顯示檔案編碼進度。

至於把程式執行後的 stdout 丟到下一隻程式的方法,應該也有不少人用過: | ,像是 cat /etc/passwd | grep dd-han 就會把 cat /etc/passwd 的執行結果(也就是整個 passwd 檔案的內容)透過 stdin 丟到 grepgrep 則會找出有 dd-han 的那行顯示出來。

那如果要把變數丟進去指令的 stdin 呢?

echo $MYVAR | grep dd-han

這是一種作法,不過這個作法有個問題,如果你的 MYVAR 內容是 -n ,因為 echo 本身可以下 -n 所以最後什麼都不會輸出。在這裡建議用另一種作法:

grep dd-han <<< $MYVAR

<<< 可以用在比較新的 Bash 與 Zsh ,如果你是比較舊版的 bash 或是要用在 sh 上,可以用下面的方法代替:

grep dd-han << EOF
$MYVAR
EOF

回到最前面的 find ,有時候 find 過程中,錯誤比結果還多,根本幫倒忙,這種時候也可以這樣下指令:

find -name myFile 2> /dev/null

反正進不去的資料夾我也沒興趣知道,直接導向 /dev/null 就看不到啦。

今天就這樣吧,遊戲還沒打先閃。


我是誰?
我是 dd-han ,可以叫我呆翰,是國立臺中科技大學的延畢生 與 創科資訊的時習生。


上一篇
[鐵人賽第06天] 下指令的小技巧(*與{})與運作方式
下一篇
[鐵人賽第08天] Command Substitution 的用法
系列文
30 天的 ShellScript 教室解決開發者的困擾23
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言